	# Closure.pm
	package Closure;
	use strict;
	
	use Carp;
	
	my @attrs = qw(size weight shape);
	
	sub new {
	   my $class = shift;
	   $class = (ref $class) || $class;
	
	   my %attrs = map {$_ => 1} @attrs;
	
	   my $object = sub {
	      my ($attr, $value) = @_;
	
	      unless (exists $attrs{$attr}) {
	         croak "Attempt to ", (defined $value)?"set":"get",
	         " invalid attribute '$attr'";
	      }
	
	      if (defined $value) {
	         my $oldv = $attrs{$attr};
	         $attrs{$attr} = $value;
	         return $oldv;
	      }
	
	      return $attrs{$attr};
	   };
	   return bless $object, $class;
	}
	
	# generate attribute methods for each valid attribute
	foreach my $attr (@attrs) {
	   eval "sub $attr {\$_[0]('$attr', \$_[1]);}";
	}
	
	1;
